package org.wangduqing.ibatisdao.util;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.text.MessageFormat;
import java.util.Iterator;
import java.util.Map;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.log4j.Logger;

public class IbatisDaoUtil {
	
	public static final String DATABASE_TYPE_MYSQL = "mysql";
	public static final String DATABASE_TYPE_SQLSERVER = "sqlserver";
	public static final String DATABASE_TYPE_ORACLE = "oracle";
	public static final String DATABASE_TYPE_POSTGRE = "postgresql";
	
	public static final String MYSQL_SQL = "select * from ({0}) sel_tab00 limit {1},{2}";
	public static final String SQLSERVER_SQL = "select * from (select rownum() over(order by tempColumn) tempRowNumber, * from (select top {1} tempColumn = 0, {0}) t ) tt where tempRowNumber > {2}";
	public static final String ORACLE_SQL = "select * from (select row_.*,rownum rownum_ from ({0}) row_ where rownum <= {1}) where rownum_ > {2})";
	public static final String POSTGREL_SQL = "select * from ({0}) sel_tab00 limit {2} offset {1}";
	
	private static final Logger logger = Logger.getLogger(IbatisDaoUtil.class);
	
	public static boolean isWrapClass(Class clz){
		
		try {
			
			return ((Class)clz.getField("TYPE").get(null)).isPrimitive();
			
		} catch (Exception e) {
			
			return false;
			
		}
		
	}
	
	public static boolean isAbstract(Method method){
		
		int mod = method.getModifiers();
		return Modifier.isAbstract(mod);
		
	}
	
	public static String getMethodSqlLogicJar(String sqlurl){
		
		StringBuffer sb = new StringBuffer();
		InputStream is = IbatisDaoUtil.class.getResourceAsStream(sqlurl);
		BufferedReader br = new BufferedReader(new InputStreamReader(is));
		String s = "";
		
		try {
			
			while((s=br.readLine())!=null)
				sb.append(s+" ");
			
		} catch (Exception e) {
			
			e.printStackTrace();
			
		}
		return sb.toString();
		
	}
	
	public static String getFirstSmall(String name){
		
		name = name.trim();
		if(name.length()>=2){
			
			return name.substring(0, 1).toLowerCase()+name.substring(1);
			
		}else{
			
			return name.toLowerCase();
			
		}
		
	}
	
	public static void populate(Object bean, Map properties) throws IllegalAccessException, InvocationTargetException{
		
		if((bean==null)||(properties==null)){
			
			return;
			
		}
		Iterator names = properties.keySet().iterator();
		while(names.hasNext()){
			
			String name = (String) names.next();
			if(name == null){
				
				continue;
				
			}
			Object value = properties.get(name);
			String camelName = CamelCaseUtils.toCamelCase(name);
			BeanUtils.setProperty(bean, camelName, value);
			
		}
		
	}
	
	public static String createPageSql(String dbtype, String sql, int page, int rows){
		
		int beginNum = (page - 1) * rows;
		String[] sqlParam = new String[3];
		sqlParam[0] = sql;
		sqlParam[1] = beginNum + "";
		sqlParam[2] = rows + "";
		String jdbcType = dbtype;
		if(jdbcType==null||"".equals(jdbcType)){
			
			throw new RuntimeException("org.jeecgframework.minidao.aop.MiniDaoHandler:(数据库类型:dbType)没有设置,请检查配置文件");
			
		}
		if(jdbcType.indexOf(DATABASE_TYPE_MYSQL)!=-1){
			
			sql = MessageFormat.format(MYSQL_SQL, sqlParam);
			
		}else if(jdbcType.indexOf(DATABASE_TYPE_POSTGRE)!=-1){
			
			sql = MessageFormat.format(POSTGREL_SQL, sqlParam);
			
		}else{
			
			int beginIndex = (page - 1) * rows;
			int endIndex = beginIndex + rows;
			sqlParam[2] = Integer.toString(beginIndex);
			sqlParam[1] = Integer.toString(endIndex);
			if(jdbcType.indexOf(DATABASE_TYPE_ORACLE)!=-1){
				
				sql = MessageFormat.format(ORACLE_SQL, sqlParam);
				
			}else if(jdbcType.indexOf(DATABASE_TYPE_SQLSERVER)!=-1){
				
				sqlParam[0] = sql.substring(getAfterSelectInsertPoint(sql));
				sql = MessageFormat.format(SQLSERVER_SQL, sqlParam);
				
			}
			
		}
		return sql;
		
	}
	
	private static int getAfterSelectInsertPoint(String sql){
		
		int selectIndex = sql.toLowerCase().indexOf("select");
		int selectDistinctIndex = sql.toLowerCase().indexOf("select distinct");
		return selectIndex + (selectDistinctIndex==selectIndex ? 15:6);
		
	}
	
	
	
}
